package com.kcht.rfid.rd30.secretary;

import com.kcht.rfid.rd30.secretary.core.command.ReaderCommand;
import com.kcht.rfid.rd30.secretary.dispatch.BaseAbnormalDetection;
import com.kcht.rfid.rd30.secretary.dispatch.BaseCommandExecute;
import com.kcht.rfid.rd30.secretary.dispatch.IReaderChannel;
import com.kcht.rfid.rd30.secretary.dispatch.Rd30Reader;
import com.kcht.rfid.rd30.secretary.dispatch.impl.CustomCommandExecutor;
import com.kcht.rfid.rd30.secretary.dispatch.impl.SwrDetection;
import com.kcht.rfid.rd30.secretary.dispatch.impl.ZmqSocketProxy;
import com.kcht.rfid.rd30.secretary.exception.NullOrEmptyCollectionException;

import java.util.HashMap;
import java.util.Map;
import java.util.Observer;

/**
 * rd30管理器
 * */
public class Rd30Manager extends DeviceIntf{
    private static DeviceIntf instance=new Rd30Manager();
    private Rd30Manager(){}
    @Override
    public void initReader(String readerIp, Map<String, String> initParams, Observer observer) {
        if (null == initParams) {
            initParams = getDefaultInitParams();
        }
        synchronized (readerMap){
            if (!readerMap.containsKey(readerIp)) {
                IReaderChannel channel=new ZmqSocketProxy(readerIp,IReaderChannel.port);
                BaseAbnormalDetection detection=new SwrDetection(observer);
                BaseCommandExecute commandExecute=new CustomCommandExecutor(initParams);
                Rd30Reader reader=new Rd30Reader(channel,detection,commandExecute);
                readerMap.put(readerIp, reader);
            }
        }
    }

    @Override
    public void disconnectReader(String readerIp) {
        Rd30Reader rd30Reader;
        synchronized (readerMap){
            rd30Reader = readerMap.get(readerIp);
            readerMap.remove(readerIp);
        }
        if(rd30Reader!=null){
            rd30Reader.disconnect();
        }
    }

    @Override
    public void dispatchReaderCommand(String readerIp, ReaderCommand cmd, Observer... observers) {
        if(observers==null||observers.length==0){
            throw new NullOrEmptyCollectionException();
        }
        Rd30Reader rd30Reader;
        synchronized (readerMap){
            rd30Reader=readerMap.get(readerIp);
        }
        if(rd30Reader!=null){
            if(cmd==null||cmd.getBasicReaderCommands().isEmpty()){
                throw new NullOrEmptyCollectionException();
            }
            rd30Reader.executeCommand(cmd,observers);
        }
    }

    @Override
    public void stopReaderWork(String readerIp) {
        Rd30Reader rd30Reader;
        synchronized (readerMap){
            rd30Reader=readerMap.get(readerIp);
        }
        if(rd30Reader!=null){
            rd30Reader.stopWork();
        }
    }

    protected Map<String, String> getDefaultInitParams() {
        Map<String, String> initParams = new HashMap<String, String>();
        initParams.put("freq", "922625");
        initParams.put("power", "14");
        initParams.put("code_type", "0");
        initParams.put("forward_rate", "80");
        initParams.put("reverse_rate", "160");
        initParams.put("ants","2");
        return initParams;
    }

    public static DeviceIntf getInstance(){
        return Rd30Manager.instance;
    }
}
